#include "app_ex_cmd.h"

#define LOG_TAG              "ex/cmd"
#include <drv_log.h>

/*************************extern****************************************/
extern dev_config dev_config_info;
extern struct rt_spi_device *spi_att7022eu;
//extern net_gprs  net_sta;
extern struct rt_semaphore sem_att7022eu_available;//采集可用信号量
extern total_protect_data *gtpd;
/*******************************************************************************
* Function Name  : get_average
* Description    : 取平均值
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
rt_uint32_t get_average(rt_uint32_t *data)
{
	rt_uint32_t min = 0,max = 0,sum = 0;
	rt_uint8_t  idx = 0;
	min = data[0];
	max = data[0];
	sum = data[0];
	for(idx = 1;idx < 5;idx++)
	{
		if(data[idx] < min)
		{
			min = data[idx];
		}
		if(data[idx] > max)
		{
			max = data[idx];
		}
		sum += data[idx];
	}
	
	return (rt_uint32_t)((sum - min -max)/3);
}
/*******************************************************************************
* Function Name  : cal_vol
* Description    : 标定六路电压
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void cal_vol(int argc, char **argv)
{
	double 			 vol = 0.0;
	double 			 ugain = 0.0;
	rt_uint32_t  read = 0;
	rt_uint32_t  input = 0;
	rt_uint32_t  cal = 0;
	cal_voltage_info  cal_voltage = {0};
	if(argc <2)
	{
		LOG_E("请输入标定电压！\n");
		return;
	}
	input = atoi(argv[1]);
	read = att7022eu_read(spi_att7022eu,0x0D);//第一个7022的A相
	vol = (int)read/8192.0;
	ugain = (input/vol - 1);
	if(ugain >= 0)
	{
		cal = (rt_uint32_t)(ugain*32768);
	}
	else
	{
		cal = (rt_uint32_t)(65535+ugain*32768);
	}
	cal_voltage.voltage_A = cal;
	LOG_I("The first voltage calibration is completed\n");
	
	read = att7022eu_read(spi_att7022eu,0x0E);//第一个7022的B相
	vol = (int)read/8192.0;
	ugain = (input/vol - 1);
	if(ugain >= 0)
	{
		cal = (rt_uint32_t)(ugain*32768);
	}
	else
	{
		cal = (rt_uint32_t)(65535+ugain*32768);
	}
	
	cal_voltage.voltage_B = cal;
	LOG_I("The second voltage calibration is completed\n");
	
	read = att7022eu_read(spi_att7022eu,0x0F);//第一个7022的C相
	vol = (int)read/8192.0;
	ugain = (input/vol - 1);
	if(ugain >= 0)
	{
		cal = (rt_uint32_t)(ugain*32768);
	}
	else
	{
		cal = (rt_uint32_t)(65535+ugain*32768);
	}
	
	cal_voltage.voltage_C = cal;
	LOG_I("The third voltage calibration is completed\n");
	cal_voltage.magic_word = MAGIC_WORD;
	ef_set_env_blob("vol_gain",&cal_voltage,VOL_GAIN_INFO_SIZE);
	LOG_I("Calibration voltage written successfully\n");
}
MSH_CMD_EXPORT(cal_vol,calibration voltage);
/*******************************************************************************
* Function Name  : cur_gain_cal
* Description    : 标定电流增益
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void cur_gain_cal(int argc, char **argv)
{
	double 			 cur = 0.0;
	double 			 ugain = 0.0;
	double  		 input = 0;
	rt_uint32_t  read[5] = {0};
	rt_uint32_t  cal = 0;
	rt_uint8_t   idx = 0;
	gain_current_info  gain_current_config_data = {0};
	if(argc <2)
	{
		LOG_E("请输入标定电流！");
		return;
	}
	
	input = atoi(argv[1])/1000.0;
	for(idx = 0;idx < 5;idx++)
	{
		rt_thread_mdelay(100);
		read[idx] = att7022eu_read(spi_att7022eu,0x10);//第一个7022的A相
	}
	cur = (double)(get_average(read)/8192.0/10.0);
	ugain = (input/cur - 1);
	if(ugain >= 0)
	{
		cal = (rt_uint32_t)(ugain*32768);
	}
	else
	{
		cal = (rt_uint32_t)(65535+ugain*32768);
	}
	gain_current_config_data.gain_current_A = cal;
	LOG_I("The first current gain calibration is completed\n");
	
	
	gain_current_config_data.magic_word = MAGIC_WORD;
	ef_set_env_blob("cur_gain",&gain_current_config_data,		 CUR_GAIN_INFO_SIZE);
	LOG_I("Calibration current gain written successfully\n");
	
}
MSH_CMD_EXPORT(cur_gain_cal,current gain calibration);
/*******************************************************************************
* Function Name  : cur_offset_cal
* Description    : 标定三路电流偏置
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void cur_offset_cal(int argc, char **argv)
{
	rt_uint32_t  read[5] = {0};
	rt_uint32_t  cal = 0;
	rt_uint32_t  average = 0;
	rt_uint8_t   idx = 0;
	offset_current_info offset_current_config_data = {0};
	
	for(idx = 0;idx < 5;idx++)
	{
		rt_thread_mdelay(100);
		read[idx] = att7022eu_read(spi_att7022eu,0x10);//第一个7022的A相
	}
	average = get_average(read);
	cal = (rt_uint32_t)(average*average/32768);
	offset_current_config_data.offset_current_A = cal;
	LOG_I("The first current offset calibration is completed\n");
	
	offset_current_config_data.magic_word = MAGIC_WORD;
	ef_set_env_blob("cur_offset",&offset_current_config_data,VOL_OFFSET_INFO_SIZE);
	LOG_I("Calibration current offset written successfully\n");
}
MSH_CMD_EXPORT(cur_offset_cal,Current offset calibration);
/*******************************************************************************
* Function Name  : reset_cal_cur
* Description    : 重置电流标定值 
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void reset_cal_cur(int argc, char **argv)
{
	gain_current_info    gain_current_config_data   = {0};
	offset_current_info  offset_current_config_data = {0};
	gain_current_config_data.magic_word = 0;
	offset_current_config_data.magic_word = 0;
	ef_set_env_blob("cur_gain",&gain_current_config_data,		 CUR_GAIN_INFO_SIZE);
	ef_set_env_blob("cur_offset",&offset_current_config_data,VOL_OFFSET_INFO_SIZE);
	LOG_I("Reset calibration current written successfully\n");
}
MSH_CMD_EXPORT(reset_cal_cur,reset cal current);
/*******************************************************************************
* Function Name  : reset_cal_vol
* Description    : 重置标定电压
* Input          : const char*
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void reset_cal_vol(int argc, char **argv)
{
	cal_voltage_info  cal_voltage = {0};
	cal_voltage.magic_word = RT_NULL;
	ef_set_env_blob("vol_gain",&cal_voltage,VOL_GAIN_INFO_SIZE);
	LOG_I("Reset calibration voltage written successfully\n");
}
MSH_CMD_EXPORT(reset_cal_vol,reest cal voltage);



